﻿namespace ufida.u9.ait.openapi
{
	using System;
	using System.Collections.Generic;
	using System.Text;
    using ufida.u9.ait.openapi.utils;
	using UFIDA.U9.AP.APAdjust;
	using UFIDA.U9.Base;
	using UFIDA.U9.Base.UOM;
	using UFIDA.U9.CBO.MFG.Routing;
	using UFIDA.U9.CBO.MFG.WorkCenter;
	using UFIDA.U9.CBO.Pub.Controller;
	using UFIDA.U9.CBO.SCM.Item;
    using UFIDA.U9.CBO.SCM.ProjectTask;
    using UFIDA.U9.PR.PurchaseRequest;
	using UFSoft.UBF.AopFrame;
	using UFSoft.UBF.Business;
	using UFSoft.UBF.Util.Context;

	/// <summary>
	/// RoutingSaveSV partial 
	/// </summary>	
	public partial class RoutingSaveSV 
	{	
		internal BaseStrategy Select()
		{
			return new RoutingSaveSVImpementStrategy();	
		}		
	}
	
	#region  implement strategy	
	/// <summary>
	/// Impement Implement
	/// 
	/// </summary>	
	internal partial class RoutingSaveSVImpementStrategy : BaseStrategy
	{
		public RoutingSaveSVImpementStrategy() { }

		public override object Do(object obj)
		{						
			RoutingSaveSV bpObj = (RoutingSaveSV)obj;

            List<CopyOfCommonArchiveDataDTOData> retlist = new List<CopyOfCommonArchiveDataDTOData>();
            try
			{
                if (bpObj.Data == null || bpObj.Data.Count == 0)
                    throw new Exception("传入参数为空");
				foreach(var dto in bpObj.Data)
				{
					if (dto.ItemMaster == null)
						throw new Exception("ItemMaster不能为空!");
                    ItemMaster item = EntityUtils.GetEntityByCode<ItemMaster>(dto.ItemMaster.Code);
                    if (String.IsNullOrEmpty(dto.RoutingVersionCode))
						throw new Exception("RoutingVersionCode不能为空!");

					Routing be = Routing.Finder.Find($"ItemMaster='{item.ID}' and RoutingVersionCode='{dto.RoutingVersionCode}'");
					if (be == null)
					{
						//新增逻辑
						be=CreateRouting(dto);
					}
					else
					{
						//修改逻辑
						UpdateRouting(dto, be);
					}
					//审核逻辑
                    ApproveRouting(be);
                    retlist.Add(new CopyOfCommonArchiveDataDTOData() { 
						ID = be.ID,
						Code=be.ItemMaster.Code,
						Name=be.ItemMaster.Name 
					});
                }
                return ResultUtils.success(bpObj, bpObj.Data, retlist);
            }
			catch(Exception ex)
			{
                return ResultUtils.error(bpObj, bpObj.Data, ex);
            }
		}

        private void ApproveRouting(Routing doc)
        {
			if (doc.Status == UFIDA.U9.CBO.MFG.Enums.MFGDocStatusEnum.Approved)
				return;
            using(ISession session = Session.Open())
			{
				doc.Status = UFIDA.U9.CBO.MFG.Enums.MFGDocStatusEnum.Approved;
				doc.IsNeedUpdateWIP = true;

				session.Commit();
            }
        }

        private void UpdateRouting(RoutingAITDTOData dto, Routing doc)
        {
            using(ISession session = Session.Open())
			{
				ModifyHead(dto, doc);
				ModifyLines(dto, doc);
				session.Commit();
			}
        }

        private void ModifyLines(RoutingAITDTOData dto, Routing doc)
        {
			//构造DTO行缓存
			Dictionary<String, OperationAITDTOData> dtolinedic = new Dictionary<string, OperationAITDTOData>();
			foreach(var dtoline in dto.Operations)
			{
				if (!dtolinedic.ContainsKey(dtoline.Sequence))
				{
                    dtolinedic.Add(dtoline.Sequence, dtoline);
				}
			}
            //构造实体行缓存
            Dictionary<String, Operation> linedic = new Dictionary<string, Operation>();
            foreach (var line in doc.Operations)
            {
                if (!linedic.ContainsKey(line.Sequence))
                {
                    linedic.Add(line.Sequence, line);
                }
            }
            //逐行修改或删除行
			List<Operation> dellist = new List<Operation>();
            foreach(var line in doc.Operations)
			{
				if (dtolinedic.ContainsKey(line.Sequence))
				{
					//修改行
					SetLineValues(line, dtolinedic[line.Sequence],doc);
				}
				else
				{
                    //删除行
                    //这里不能line.Remove(),会导致集合发生变化,报错
                    dellist.Add(line);
				}
			}
			foreach(var line in dellist)
			{
				line.Remove();
			}

			//新增行
            foreach (var dtoline in dto.Operations)
			{
				//循环DTO行
				if (!linedic.ContainsKey(dtoline.Sequence))
				{
					//新增行
					Operation line = Operation.Create(doc);
                    SetLineValues(line, dtoline, doc);
				}
			}

        }

		/// <summary>
		/// 设置行属性
		/// </summary>
		/// <param name="line"></param>
		/// <param name="dtoline"></param>
		/// <param name="doc"></param>
        private void SetLineValues(Operation line, OperationAITDTOData dtoline, Routing doc)
        {
            line.Sequence = dtoline.Sequence;
            line.WorkCenter = EntityUtils.GetEntityByCode<WorkCenter>(dtoline.WorkCenter);
            line.TimeUOM = EntityUtils.GetEntityByCode<UOM>(dtoline.TimeUOM);
            if (dtoline.StdOperation != null)
            {
                line.StdOperation = EntityUtils.GetEntityByCode<StdOperation>(dtoline.StdOperation);
                line.TimeUOMKey = line.StdOperation.TimeUOMKey;

            }
            line.Description = dtoline.Description;
			line.SetupTime=dtoline.SetupTime;
			line.RunTime=dtoline.RunTime;

            //扩展字段处理
            if (dtoline.DescFlexField != null)
            {
                line.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
                DTOUtils.DTOPropCopy(dtoline.DescFlexField, line.DescFlexField);
            }

            //其他
            line.OrgKey = doc.OrgKey;
            line.CapStartTimeUOMKey = line.TimeUOMKey;
            line.CapacityTimeUOMKey = line.TimeUOMKey;
            line.OrgKey = doc.OrgKey;
            line.OutputUOMKey = doc.ProductUOMKey;
            line.OutputBaseUOMKey = doc.ProductUOM.BaseUOMKey;
            line.OutputUOMRatio2PU = 1;
            line.OutputUOMRatio2Base = 1;
            line.Yield = 1;
            line.MinTransQty = 1;
            line.IsRollupCost = true;
            line.IsRcvDirectly = true;
            line.IsCountPoint = true;
            line.IsBackOthers = true;
            line.IsBackMaterial = true;
            line.IsBackMachine = true;
            line.IsBackLabor = true;
            line.IsAutoCharge = true;
            line.ComTimeNum = 1;

        }

        private void ModifyHead(RoutingAITDTOData dto, Routing be)
        {
			SetHeadValues(dto, be);
        }

        private void SetHeadValues(RoutingAITDTOData dto, Routing doc)
        {
            doc.RoutingVersionCode = dto.RoutingVersionCode;
            doc.EffectiveDate = DateTime.Parse(dto.EffectiveDate);
            doc.DisableDate = DateTime.Parse(dto.DisableDate);
            doc.Project = EntityUtils.GetEntityByCode<Project>(dto.Project);//项目
			doc.Description= dto.Description;


            doc.Lot = 1; //生产批量
            doc.IsPrimaryLot = true; //主批量
            doc.CumYield = 1; //累计工序产出率
            doc.IsCostRoll = true; //成本卷积默认

            //扩展字段处理
            if (dto.DescFlexField != null)
            {
                doc.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments();
                DTOUtils.DTOPropCopy(dto.DescFlexField, doc.DescFlexField);
            }

        }

        private Routing CreateRouting(RoutingAITDTOData dto)
        {
			Routing doc=null;
            using (ISession session = Session.Open())
            {
				doc = CreateHead(dto);
				CreateLine(doc, dto);
                session.Commit();
            }
			return doc;
        }

        private void CreateLine(Routing doc, RoutingAITDTOData dto)
        {
            foreach (var dtoline in dto.Operations)
			{
				Operation line = Operation.Create(doc);
				SetLineValues(line, dtoline, doc);
            }
        }

        private Routing CreateHead(RoutingAITDTOData dto)
        {
			//创建表头
			Routing doc = Routing.Create();
			doc.OrgKey = Context.LoginOrg.Key;
			ItemMaster item= EntityUtils.GetEntityByCode<ItemMaster>(dto.ItemMaster.Code);
			doc.ItemMasterKey = item.Key;
			doc.ProductUOMKey = item.ManufactureUOMKey;
			//设置表头字段
			SetHeadValues(dto, doc);

            return doc;
        }
    }

	#endregion
	
	
}